<template>
  <img
    :class="['lazy', className]"
    :src="defaultImg"
    :data-src="url"
    :data-srcset="`${url} 1x`"
    alt="fordeal"
  />
</template>

<script>
import {onMounted,onUpdated} from 'vue'
export default {
    name:"ImgLazy",
    props: {
        url: {
            type: String
        },
        defaultImg: {
            type: String,
            default: require(`@/assets/images/img_default_300x300.jpg`)
        },
        className: {
            type: String,
            default: ''
        }
    },
    setup(props) {
        onMounted(()=>{
            LazyLoad();
        })
        onUpdated(()=>{
            LazyLoad();
        })
        function LazyLoad() {
            // 这个active是节流throttle所用的标志位，这里用到了闭包知识
            let active = false;
            
            const lazyLoad = () => {
                // throttle相关：200ms内只会执行一次lazyLoad方法
                if (active) return;
                active = true;
                setTimeout(() => {
                    // 获取所有class为lazy的img标签，这里由于之前已经把处理过的img标签的class删掉了  所以不会重复查找
                    let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
                    lazyImages.forEach(lazyImage => {
                        // 判断元素是否进入viewport
                        if (isInViewport(lazyImage)) {
                        // <img class="lazy" src="[占位图]" data-src="[真实url地址]" data-srcset="[不同屏幕密度下，不同的url地址]" alt="I'm an image!">
                        // ele.dataset.* 可以读取自定义属性集合，比如data-*
                        // img.srcset 属性用于设置不同屏幕密度下，image自动加载不同的图片  比如<img src="image-128.png" srcset="image-256.png 2x" />
                        if(lazyImage.src !== lazyImage.dataset.src){
                            lazyImage.src = lazyImage.dataset.src;
                            lazyImage.srcset = lazyImage.dataset.srcset;
                        }
                        
                        // 删除class  防止下次重复查找到改img标签
                        // lazyImage.classList.remove("lazy");
                        }
                
                        // 当全部处理完了，移除监听
                        if (lazyImages.length === 0) {
                        document.removeEventListener("scroll", lazyLoad);
                        window.removeEventListener("resize", lazyLoad);
                        window.removeEventListener("orientationchange", lazyLoad);
                        }
                    })
                
                    active = false;
                }, 200);
            }
            function isInViewport(ele) {
                // 元素顶部 距离 视口左上角 的距离top <= 窗口高度 （反例：元素在屏幕下方的情况）
                // 元素底部 距离 视口左上角 的距离bottom > 0 (反例：元素在屏幕上方的情况)
                // 元素display样式不为none
                const notBelow = ele.getBoundingClientRect().top <= window.innerHeight ? true : false;
                const notAbove = ele.getBoundingClientRect().bottom >= 0 ? true : false;
                const visable = getComputedStyle(ele).display !== "none" ? true : false;
                return notBelow && notAbove && visable ? true : false;
            }
          
            lazyLoad();
            document.addEventListener("scroll", lazyLoad);
            document.addEventListener("resize", lazyLoad);
            document.addEventListener("orientationchange", lazyLoad);
        }
    }
}

</script>

<style lang='scss' scoped>
</style>
